/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "highlighter.h"

//! [0]
Highlighter::Highlighter(QTextDocument *parent)
    : QSyntaxHighlighter(parent)
{
    HighlightingRule rule;

    keywordFormat.setForeground(Qt::darkBlue);
    keywordFormat.setFontWeight(QFont::Bold);
    QStringList keywordPatterns;
//    keywordPatterns << "\\bchar\\b" << "\\bclass\\b" << "\\bconst\\b"
//                    << "\\bdouble\\b" << "\\benum\\b" << "\\bexplicit\\b"
//                    << "\\bfriend\\b" << "\\binline\\b" << "\\bint\\b"
//                    << "\\blong\\b" << "\\bnamespace\\b" << "\\boperator\\b"
//                    << "\\bprivate\\b" << "\\bprotected\\b" << "\\bpublic\\b"
//                    << "\\bshort\\b" << "\\bsignals\\b" << "\\bsigned\\b"
//                    << "\\bslots\\b" << "\\bstatic\\b" << "\\bstruct\\b"
//                    << "\\btemplate\\b" << "\\btypedef\\b" << "\\btypename\\b"
//                    << "\\bunion\\b" << "\\bunsigned\\b" << "\\bvirtual\\b"
//                    << "\\bvoid\\b" << "\\bvolatile\\b";

    keywordPatterns << "ABORT" << "CREATE" << "FROM" << "NATURAL"
                    << "ACTION" << "CROSS" << "FULL" << "NO"
                    << "ADD" << "CURRENT_DATE" << "GLOB" << "NOT"
                    << "AFTER" << "CURRENT_TIME" << "GROUP" << "NOTNULL"
                    << "ALL" << "CURRENT_TIMESTAMP" << "HAVING" << "nullptr"
                    << "ALTER" << "DATABASE" << "IF" << "OF"
                    << "ANALYZE" << "DEFAULT" << "IGNORE" << "OFFSET"
                    << "AND" << "DEFERRABLE" << "IMMEDIATE" << "ON"
                    << "AS" << "DEFERRED" << "IN" << "OR"
                    << "ASC" << "DELETE" << "INDEX" << "ORDER"
                    << "ATTACH" << "DESC" << "INDEXED" << "OUTER"
                    << "AUTOINCREMENT" << "DETACH" << "INITIALLY" << "PLAN"
                    << "BEFORE" << "DISTINCT" << "INNER" << "PRAGMA"
                    << "BEGIN" << "DROP" << "INSERT" << "PRIMARY"
                    << "BETWEEN" << "EACH" << "INSTEAD" << "QUERY"
                    << "BY" << "ELSE" << "INTERSECT" << "RAISE"
                    << "CASCADE" << "END" << "INTO" << "RECURSIVE"
                    << "CASE" << "ESCAPE" << "IS" << "REFERENCES"
                    << "CAST" << "EXCEPT" << "ISNULL" << "REGEXP"
                    << "CHECK" << "EXCLUSIVE" << "JOIN" << "REINDEX"
                    << "COLLATE" << "EXISTS" << "KEY" << "RELEASE"
                    << "COLUMN" << "EXPLAIN" << "LEFT" << "RENAME"
                    << "COMMIT" << "FAIL" << "LIKE" << "REPLACE"
                    << "CONFLICT" << "FOR" << "LIMIT" << "RESTRICT"
                    << "CONSTRAINT" << "FOREIGN" << "MATCH" << "RIGHT"
                    << "SELECT" << "WHERE" << "UNIQUE" << "TRANSACTION";

    foreach (const QString &pattern, keywordPatterns) {
        QString pattern2 = "\\b" + pattern + "\\b";
        QRegExp rx(pattern2);
        rx.setCaseSensitivity(Qt::CaseInsensitive);
        rule.pattern = rx;
        rule.format = keywordFormat;
        highlightingRules.append(rule);
//! [0] //! [1]
    }
//! [1]

//! [2]
//    classFormat.setFontWeight(QFont::Bold);
//    classFormat.setForeground(Qt::darkMagenta);
//    rule.pattern = QRegExp("\\bQ[A-Za-z]+\\b");
//    rule.format = classFormat;
//    highlightingRules.append(rule);
//! [2]

//! [3]
    singleLineCommentFormat.setForeground(Qt::red);
    rule.pattern = QRegExp("--[^\n]*");
    rule.format = singleLineCommentFormat;
    highlightingRules.append(rule);

    //multiLineCommentFormat.setForeground(Qt::red);
//! [3]

//! [4]
//    quotationFormat.setForeground(Qt::darkGreen);
//    rule.pattern = QRegExp("\".*\"");
//    rule.format = quotationFormat;
//    highlightingRules.append(rule);
//! [4]

//! [5]
//    functionFormat.setFontItalic(true);
//    functionFormat.setForeground(Qt::blue);
//    rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\()");
//    rule.format = functionFormat;
//    highlightingRules.append(rule);
//! [5]

//! [6]
//    commentStartExpression = QRegExp("/\\*");
//    commentEndExpression = QRegExp("\\*/");
}
//! [6]

//! [7]
void Highlighter::highlightBlock(const QString &text)
{
    foreach (const HighlightingRule &rule, highlightingRules) {
        QRegExp expression(rule.pattern);
        int index = expression.indexIn(text);
        while (index >= 0) {
            int length = expression.matchedLength();
            setFormat(index, length, rule.format);
            index = expression.indexIn(text, index + length);
        }
    }
//! [7] //! [8]
    setCurrentBlockState(0);
//! [8]

////! [9]
//    int startIndex = 0;
//    if (previousBlockState() != 1)
//        startIndex = commentStartExpression.indexIn(text);

////! [9] //! [10]
//    while (startIndex >= 0) {
////! [10] //! [11]
//        int endIndex = commentEndExpression.indexIn(text, startIndex);
//        int commentLength;
//        if (endIndex == -1) {
//            setCurrentBlockState(1);
//            commentLength = text.length() - startIndex;
//        } else {
//            commentLength = endIndex - startIndex
//                            + commentEndExpression.matchedLength();
//        }
//        setFormat(startIndex, commentLength, multiLineCommentFormat);
//        startIndex = commentStartExpression.indexIn(text, startIndex + commentLength);
//    }
}
//! [11]
